<template>
  <div class="sankey-page">
    <!-- 查询区域：使用 BeForm -->
    <BeForm ref="formRef" :fields="searchFields" :colProps="{ span: 6 }" @search="onSearch" showAction showSearchButton showResetButton :defultValue="formModel"></BeForm>

    <!-- 图表容器 -->
    <div class="chart-container" v-loading="loading">
      <div ref="chartRef" class="echart-sankey" v-show="!isEmpty" />
      <a-empty v-show="isEmpty" />
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import type { Ref } from 'vue'
import { message } from 'ant-design-vue'
import { dataFlowCharteringApi } from '@/api/data-flow-chartering'
// ECharts 按需引入（Sankey）
import * as echarts from 'echarts/core'
import { SankeyChart } from 'echarts/charts'
import { TooltipComponent, LegendComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
echarts.use([SankeyChart, TooltipComponent, LegendComponent, CanvasRenderer])

// ---------- 表单字段配置（BeForm 风格） ----------
const formRef = ref<any>(null)
const domainsOptions = ref([])
const requestNetworkOptions = ref([])
const formModel = ref({
  domains: [] as string[],
  sensitiveType: '',
  requestNetwork: [] as string[]
})
const searchFields = ref([
  {
    label: '站点',
    prop: 'domains',
    component: 'Select',
    componentProps: {
      placeholder: '请选择',
      multiple: true,
      options: domainsOptions.value,
      mode: 'multiple',
      maxTagCount: 2,
      fieldNames: {
        label: 'site',
        value: 'site'
      }
    }
  },
  { label: '敏感类型', prop: 'sensitiveType', component: 'Input', componentProps: { placeholder: '请输入' } },
  {
    label: '请求网络域',
    prop: 'requestNetwork',
    component: 'Select',
    componentProps: {
      placeholder: '请选择',
      options: requestNetworkOptions.value,
      mode: 'multiple',
      fieldNames: {
        label: 'name',
        value: 'type'
      }
    }
  }
])
// ---------- ECharts refs ----------
const chartRef: Ref<HTMLDivElement | null> = ref(null)
let chartInstance: echarts.ECharts | null = null
type SankeyNode = { name: string }
type SankeyLink = { source: string; target: string; value: number }
const isEmpty = ref(false)
const loading = ref(false)
const fetchSankeyData = async (params: any) => {
  const res = await dataFlowCharteringApi.getListPattern({ data: params })
  let result = JSON.parse(res.data)
  let data = {}

  if (result.code == 200 && result.result) {
    data = {
      nodes: result.result.nodes,
      links: result.result.flow_link
    }
  } else {
    data = {
      nodes: [],
      links: []
    }
  }
  return { data }
}

// ---------- 图表配置和渲染 ----------
const renderChart = (nodes: SankeyNode[], links: SankeyLink[]) => {
  // let data: any = []
  // 节点颜色列表（保留 rgb 格式，渐变由 link 使用节点颜色）
  const colorList = [
    'rgb(59,93,233)',
    'rgb(240,72,100)',
    'rgb(24,144,255)',
    'rgb(166,169,133)',
    'rgb(30,157,211)',

    'rgb(219,207,54)',
    'rgb(219,207,54)',
    'rgb(172,216,47)',
    'rgb(172,216,47)',
    'rgb(139,62,153)',
    'rgb(166,169,113)',
    'rgb(166,169,113)'
  ]
  // 计算所有作为 source 的节点名（用来判定哪些节点是“右侧”/sink）
  const sourceSet = new Set<string>(links.map((l) => l.source))
  const data = nodes.map((n, i) => {
    const isSink = !sourceSet.has(n.name) // 没有作为 source 的就是右侧节点
    return {
      name: n.name,
      itemStyle: { color: colorList[i] },
      // 覆盖单个节点的 label：右侧节点显示在左边，其它显示在右边
      label: {
        position: isSink ? 'left' : 'right',
        fontSize: 14,
        color: '#656565'
      }
    }
  })

  // 如果想对每条连线单独指定样式也可以在 links 中加入 lineStyle 字段。
  const linksWithStyle = links.map((l) => ({
    ...l,
    // 指定每条 link 使用渐变（由 source->target 两端节点色构成），并统一 opacity 为 0.5
    lineStyle: {
      color: 'gradient', // 'gradient' | 'source' | 'target'
      opacity: 0.4,
      curveness: 0.2 // 可调节弧度
    }
  }))

  const option = {
    tooltip: {
      trigger: 'item',
      triggerOn: 'mousemove',
      formatter: (params: any) => {
        if (params.dataType === 'edge') {
          return `资产【${params.data.source} 】传输【${params.data.target} 】次数: ${params.data.value}`
        }
        return params.name
      }
    },
    series: {
      type: 'sankey',
      layoutIterations: 32,
      emphasis: {
        focus: 'adjacency'
      },
      data: data,
      links: linksWithStyle,
      left: '0.5%', // 左边距
      right: '0.5%', // 右边距
      width: '99%', // 图表宽度
      label: {
        color: '#656565',
        fontSize: 14
      },
      itemStyle: {
        borderWidth: 0
      },
      lineStyle: {
        color: 'gradient',
        opacity: 0.5,
        curveness: 0.3
      }
    }
  }

  chartInstance?.setOption(option, true)
  window.addEventListener('resize', () => {
    chartInstance?.resize()
  })
}

// 窗口 resize 处理
const onResize = () => {
  chartInstance?.resize()
}

const onSearch = async (values: any) => {
  try {
    let params: any = {
      domains: values.domains ? values.domains : [],
      net_scope_ids: values.requestNetwork ? values.requestNetwork : [],
      sensitive_classify: values.sensitiveType ? [values.sensitiveType] : []
    }
    loading.value = true
    // 调用 mock/真实接口
    const resp: any = await fetchSankeyData(params)
    if (resp.data.links.length === 0) {
      isEmpty.value = true
      return
    } else {
      isEmpty.value = false
    }
    nextTick(() => {
      renderChart(resp.data.nodes, resp.data.links)
    })
    setTimeout(() => {
      renderChart(resp.data.nodes, resp.data.links)
    }, 500)
  } catch (err) {
    isEmpty.value = true
    console.error(err)
  } finally {
    loading.value = false
  }
}

// ---------- 生命周期 ----------
onMounted(async () => {
  const res = await dataFlowCharteringApi.getListSite({ data: { page_num: '1', page_size: '200' } })
  const site = JSON.parse(res.data)
  if (site.result && site.result.data && site.result.data.length > 0) {
    domainsOptions.value = site.result.data
  } else {
    domainsOptions.value = []
  }

  //修改的地方
  // const res02 = await dataFlowCharteringApi.getListNetwork()
  // const netWork = JSON.parse(res02.data)
  const netWork = { result: '' }
  if (netWork.result && netWork.result.length > 0) {
    // requestNetworkOptions.value = netWork.result
    requestNetworkOptions.value = []
  } else {
    requestNetworkOptions.value = []
  }
  searchFields.value = searchFields.value.map((item) => {
    if (item.prop === 'domains') {
      item.componentProps.options = domainsOptions.value
    }
    if (item.prop === 'requestNetwork') {
      item.componentProps.options = requestNetworkOptions.value
    }
    return item
  })
  window.addEventListener('resize', onResize)
  if (chartRef.value) {
    chartInstance = echarts.init(chartRef.value)
  }

  nextTick(() => {
    formModel.value = {
      domains:
        domainsOptions.value.length === 0 ? [] : domainsOptions.value.length > 3 ? domainsOptions.value.slice(0, 3).map((item: any) => item.site) : domainsOptions.value.map((item: any) => item.site),
      requestNetwork: [],
      sensitiveType: ''
    }
    formRef.value?.updateFormModal(formModel.value)
    // 首次渲染：默认查询
  })
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onResize)
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
})
</script>

<style scoped lang="scss">
.sankey-page {
  padding: 12px 12px;
  background: var(--color-white);
  height: 100%;
  .be-form {
    padding: 0px 0 10px 0px !important;
    :deep(.ant-form-item) {
      margin-bottom: 0px !important;
      .ant-form-item-label {
        width: auto !important;
      }
    }
  }
  .chart-container {
    padding: 12px;
    background: #fff;
    border-radius: 4px;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.04);
    border: 1px solid #ccc;
    height: calc(100% - 60px);
    .ant-empty {
      margin-top: 40px;
    }
  }

  .echart-sankey {
    width: 100% !important;
    height: 100%; /* 可根据需要调整或做自适应容器 */
  }
}
</style>
